package genstream

import scaladuct.Extensible
import java.io.{OutputStream, InputStream}

/**
 * Created by IntelliJ IDEA.
 * User: zslajchrt
 * Date: 12.4.11
 * Time: 12:15
 * To change this template use File | Settings | File Templates.
 */

/**
 * The holder of an input stream accompanied with metadata (the transfer object pattern). InputStreamIterator
 * returns a sequence of instances of this trait. The metadata are represented by trait Extensible.
 */
trait InputStreamHolder extends Extensible {
  /**
   * The returned input stream is already open. This method does not open it.
   * The user of this holder is NOT responsible for closing the input stream. It is the responsibility of the IS iterator
   * that returns this holder.
   */
  def getInputStream(): InputStream
}

trait InputStreamIterator extends Extensible {
  /**
   * Returns the next holder in the sequence or null if there is no next IS holder. The user of this instance
   * DOES NOT HAVE TO to iterate through all holders.
   */
  def next(): InputStreamHolder

  /**
   * Closes the stream. It can be called even before reaching the end of the streams sequence.
   * It is the responsibility of this instance's user to call this method when it no longed needs to use it.
   */
  def close()
}

trait FragmentedOutputStream extends OutputStream with Extensible {
  /**
   * This callback method is called right before a new fragment is started.
   * The metadata is analogous to the metadata represented by extensions in InputStreamHolder.
   */
  def onStartFragment(metadata: Extensible)

  /**
   * This callback method is called right after new fragment is started.
   */
  def onEndFragment()
}

/**
 * This trait provides the context for streaming operations upon resources.
 */
trait StreamingContext extends Extensible

/**
 * The input resource representation.
 */
trait InputResource extends Extensible {
  /**
   * Opens a new IS iterator
   */
  def openIterator(context: StreamingContext): InputStreamIterator
}

/**
 * The output resource representation.
 */
trait OutputResource extends Extensible {
  /**
   * Opens a new fragmented output stream. It is the responsibility of the caller (the user) of this method
   * to close the returned output stream.
   */
  def openFragmentedOutputStream(context: StreamingContext): FragmentedOutputStream
}
